home *** CD-ROM | disk | FTP | other *** search
/ X User Tools / X User Tools (O'Reilly and Associates)(1994).ISO / sources / xman / buttons.c < prev    next >
C/C++ Source or Header  |  1994-09-27  |  22KB  |  741 lines

  1. /*
  2.  * xman - X window system manual page display program.
  3.  *
  4.  * $XConsortium: buttons.c,v 1.32 91/09/03 17:41:59 dave Exp $
  5.  *
  6.  * Copyright 1987, 1988 Massachusetts Institute of Technology
  7.  *
  8.  * Permission to use, copy, modify, and distribute this software and its
  9.  * documentation for any purpose and without fee is hereby granted, provided
  10.  * that the above copyright notice appear in all copies and that both that
  11.  * copyright notice and this permission notice appear in supporting
  12.  * documentation, and that the name of M.I.T. not be used in advertising or
  13.  * publicity pertaining to distribution of the software without specific,
  14.  * written prior permission.  M.I.T. makes no representations about the
  15.  * suitability of this software for any purpose.  It is provided "as is"
  16.  * without express or implied warranty.
  17.  *
  18.  * Author:    Chris D. Peterson, MIT Project Athena
  19.  * Created:   October 27, 1987
  20.  */
  21.  
  22. #include "globals.h"
  23.  
  24. /* The files with the icon bits in them. */
  25.  
  26. #include "icon_open.h"
  27. #include "icon_help.h"
  28. #include "iconclosed.h"
  29.  
  30. static void CreateOptionMenu(), CreateSectionMenu();
  31. static void StartManpage();
  32. static Widget * ConvertNamesToWidgets();
  33. ManpageGlobals * InitPsuedoGlobals();
  34.  
  35. /*    Function Name: MakeTopBox
  36.  *    Description: This funtion creates the top menu, in a shell widget.
  37.  *    Arguments: none.
  38.  *    Returns: the top level widget
  39.  */
  40.  
  41. #define TOPARGS 5
  42.  
  43. static Atom wm_delete_window;
  44.  
  45. Widget top;            /* needed in PopupWarning, misc.c */
  46.  
  47. void
  48. MakeTopBox()
  49. {
  50.   Widget form, command, label; /* widgets. */
  51.   Arg arglist[TOPARGS];        /* An argument list */
  52.   Cardinal num_args = 0;    /* The number of arguments. */
  53.   ManpageGlobals * man_globals;
  54.   static char * full_size[] = {
  55.     "topLabel", MANPAGE_BUTTON, NULL
  56.   };
  57.   static char * half_size[] = {
  58.     HELP_BUTTON, QUIT_BUTTON, NULL
  59.   };
  60.   
  61. /* create the top icon. */
  62.  
  63.   num_args = 0;
  64.   XtSetArg(arglist[num_args], XtNiconPixmap,
  65.        XCreateBitmapFromData( XtDisplay(initial_widget), 
  66.                  XtScreen(initial_widget)->root,
  67.                  (char *)iconclosed_bits, iconclosed_width,
  68.                  iconclosed_height));
  69.   num_args++;
  70.   XtSetArg(arglist[num_args], XtNtitle, resources.title);
  71.   num_args++;
  72.   XtSetArg(arglist[num_args], XtNiconic, resources.iconic);
  73.   num_args++;
  74.   top = XtCreatePopupShell(TOPBOXNAME, topLevelShellWidgetClass, 
  75.                initial_widget, arglist, num_args);
  76.  
  77.   form = XtCreateManagedWidget("form", formWidgetClass, top, 
  78.                    NULL, (Cardinal) 0);
  79.  
  80.   label = XtCreateManagedWidget("topLabel", labelWidgetClass, form, 
  81.                    NULL, (Cardinal) 0);
  82.  
  83.   num_args = 0;
  84.   XtSetArg(arglist[num_args], XtNfromVert, label); num_args++;
  85.   command = XtCreateManagedWidget(HELP_BUTTON, commandWidgetClass, form, 
  86.                   arglist, num_args);
  87.  
  88.   /* use same vertical as help widget. */
  89.   XtSetArg(arglist[num_args], XtNfromHoriz, command); num_args++;
  90.   command = XtCreateManagedWidget(QUIT_BUTTON, commandWidgetClass, form, 
  91.                   arglist, num_args);
  92.  
  93.   num_args = 0;
  94.   XtSetArg(arglist[num_args], XtNfromVert, command); num_args++;
  95.   command = XtCreateManagedWidget(MANPAGE_BUTTON, commandWidgetClass, form, 
  96.                   arglist, num_args);
  97.  
  98.   help_widget = NULL;        /* We have not seen the help yet. */
  99.  
  100.   FormUpWidgets(form, full_size, half_size);
  101.  
  102.   XtRealizeWidget(top);
  103.                 /* add WM_COMMAND property */
  104.   XSetCommand(XtDisplay(top), XtWindow(top), saved_argv, saved_argc);
  105.  
  106.   man_globals = (ManpageGlobals*) XtMalloc( (Cardinal) sizeof(ManpageGlobals));
  107.   man_globals->label = NULL;
  108.   man_globals->manpagewidgets.directory = NULL;
  109.   man_globals->manpagewidgets.manpage = NULL;
  110.   man_globals->manpagewidgets.box = NULL;
  111.   man_globals->current_directory = 0;
  112.   MakeSearchWidget(man_globals, top);
  113.   MakeSaveWidgets(man_globals, top);
  114.  
  115.   SaveGlobals( (man_globals->This_Manpage = top), man_globals);
  116.   XtMapWidget(top);
  117.   AddCursor(top, resources.cursors.top);
  118.  
  119. /*
  120.  * Set up ICCCM delete window.
  121.  */
  122.   wm_delete_window = XInternAtom(XtDisplay(top), "WM_DELETE_WINDOW",
  123.                  False);
  124.   XtOverrideTranslations
  125.       (top, XtParseTranslationTable ("<Message>WM_PROTOCOLS: Quit()"));
  126.   (void) XSetWMProtocols (XtDisplay(top), XtWindow(top),
  127.               &wm_delete_window, 1);
  128.   
  129.  
  130. }
  131.  
  132. /*    Function Name: CreateManpage
  133.  *    Description: Creates a new manpage.
  134.  *    Arguments: none.
  135.  *    Returns: none.
  136.  */
  137.  
  138. Widget
  139. CreateManpage( file )
  140. FILE * file;
  141. {
  142.   ManpageGlobals * man_globals;    /* The psuedo global structure. */
  143.  
  144.   man_globals = InitPsuedoGlobals();
  145.   CreateManpageWidget(man_globals, MANNAME, TRUE);
  146.   
  147.   if (file == NULL)
  148.     StartManpage( man_globals, OpenHelpfile(man_globals), FALSE );
  149.   else {
  150.     OpenFile(man_globals, file);
  151.     StartManpage( man_globals, FALSE, TRUE);
  152.   }
  153.   return(man_globals->This_Manpage);
  154. }
  155.  
  156. /*    Function Name: InitPsuedoGlobals
  157.  *    Description: Initializes the psuedo global variables.
  158.  *    Arguments: none.
  159.  *    Returns: a pointer to a new pseudo globals structure.
  160.  */
  161.  
  162. ManpageGlobals * 
  163. InitPsuedoGlobals()
  164. {
  165.   ManpageGlobals * man_globals;
  166.  
  167.   /*
  168.    * Allocate necessary memory. 
  169.    */
  170.  
  171.   man_globals = (ManpageGlobals *) 
  172.                 XtMalloc( (Cardinal) sizeof(ManpageGlobals));
  173.  
  174.   man_globals->section_name = (char **) XtMalloc( (Cardinal) (sections *
  175.                                   sizeof(char *)));
  176.   man_globals->manpagewidgets.box = (Widget *) XtCalloc( (Cardinal) sections,
  177.                             (Cardinal) sizeof(Widget));
  178.   
  179.   /* Initialize the number of screens that will be shown */
  180.  
  181.   man_globals->both_shown = resources.both_shown_initial;
  182.   
  183.   return(man_globals);
  184. }
  185.   
  186. /*    Function Name: CreateManpageWidget
  187.  *    Description: Creates a new manual page widget.
  188.  *    Arguments: man_globals - a new man_globals structure.
  189.  *                 name         - name of this shell widget instance.
  190.  *                 full_instance - if true then create a full manpage,
  191.  *                                 otherwise create stripped down version
  192.  *                                 used for help.
  193.  *    Returns: none
  194.  */
  195.  
  196. #define MANPAGEARGS 10
  197.  
  198. void
  199. CreateManpageWidget(man_globals, name, full_instance)
  200. ManpageGlobals * man_globals;
  201. char * name;
  202. Boolean full_instance;
  203. {
  204.   Arg arglist[MANPAGEARGS];    /* An argument list for widget creation */
  205.   Cardinal num_args;        /* The number of arguments in the list. */
  206.   Widget top, pane, hpane, sections;    /* Widgets */
  207.   ManPageWidgets * mpw = &(man_globals->manpagewidgets);
  208.  
  209.   num_args = (Cardinal) 0;
  210.   XtSetArg(arglist[num_args], XtNwidth, default_width);
  211.   num_args++; 
  212.   XtSetArg(arglist[num_args], XtNheight, default_height);
  213.   num_args++; 
  214.  
  215.   top = XtCreatePopupShell(name, topLevelShellWidgetClass, initial_widget,
  216.                arglist, num_args);
  217.  
  218.   man_globals->This_Manpage = top; /* pointer to root widget of Manualpage. */
  219.   num_args = 0;
  220.   if (full_instance)
  221.     XtSetArg(arglist[num_args], XtNiconPixmap,
  222.          XCreateBitmapFromData( XtDisplay(top), XtScreen(top)->root,
  223.                    (char *)icon_open_bits, icon_open_width,
  224.                    icon_open_height));
  225.   else 
  226.     XtSetArg(arglist[num_args], XtNiconPixmap,
  227.          XCreateBitmapFromData( XtDisplay(top), XtScreen(top)->root,
  228.                    (char *)icon_help_bits, icon_help_width,
  229.                    icon_help_height));
  230.   num_args++;
  231.   XtSetValues(top, arglist, num_args);
  232.  
  233.   pane = XtCreateManagedWidget("Manpage_Vpane", panedWidgetClass, top, NULL, 
  234.                    (Cardinal) 0);
  235.  
  236. /* Create menu bar. */
  237.  
  238.   hpane = XtCreateManagedWidget("horizPane", panedWidgetClass,
  239.                   pane, NULL, (Cardinal) 0);
  240.   num_args = 0;
  241.   XtSetArg(arglist[num_args], XtNmenuName, OPTION_MENU); num_args++;
  242.   (void) XtCreateManagedWidget("options", menuButtonWidgetClass,
  243.                   hpane, arglist, num_args);
  244.  
  245.   CreateOptionMenu(man_globals, top);
  246.  
  247.   num_args = 0;
  248.   XtSetArg(arglist[num_args], XtNmenuName, SECTION_MENU); num_args++;
  249.   sections = XtCreateManagedWidget("sections", menuButtonWidgetClass,
  250.                    hpane, arglist, num_args);
  251.  
  252.   XtSetArg(arglist[0], XtNlabel, SHOW_BOTH);
  253.   XtSetValues(man_globals->both_screens_entry, arglist, (Cardinal) 1);
  254.  
  255.   if (full_instance) {
  256.     MakeSearchWidget(man_globals, top);
  257.     CreateSectionMenu(man_globals, top);
  258.     MakeSaveWidgets(man_globals, top);
  259.   } else {
  260.     XtSetSensitive(sections, FALSE);       
  261.     XtSetArg(arglist[0], XtNsensitive, FALSE);
  262.     XtSetValues(man_globals->dir_entry, arglist, ONE);
  263.     XtSetValues(man_globals->manpage_entry, arglist, ONE);
  264.     XtSetValues(man_globals->help_entry, arglist, ONE);
  265.     XtSetValues(man_globals->search_entry, arglist, ONE);
  266.     XtSetValues(man_globals->both_screens_entry, arglist, ONE);
  267.   }
  268.  
  269.   man_globals->label = XtCreateManagedWidget(MANNAME, labelWidgetClass,
  270.                          hpane, NULL, (Cardinal) 0);
  271.  
  272. /* Create Directory */
  273.  
  274.   if (full_instance) {
  275.     num_args = 0;
  276.     XtSetArg(arglist[num_args], XtNallowVert, TRUE);
  277.     num_args++;
  278.     
  279.     mpw->directory = XtCreateWidget(DIRECTORY_NAME, viewportWidgetClass,
  280.                     pane, arglist, num_args);
  281.     
  282.     man_globals->current_directory = INITIAL_DIR;
  283.     MakeDirectoryBox(man_globals, mpw->directory,
  284.              mpw->box + man_globals->current_directory, 
  285.              man_globals->current_directory );
  286.     XtManageChild(mpw->box[man_globals->current_directory]);
  287.   }
  288.  
  289. /* Create Manpage */
  290.  
  291.   mpw->manpage = XtCreateWidget(MANUALPAGE, scrollByLineWidgetClass,
  292.                 pane, NULL, (Cardinal) 0);
  293.  
  294. }
  295.  
  296. /*    Function Name: StartManpage
  297.  *    Description: Starts up a new manpage.
  298.  *    Arguments: man_globals - the psuedo globals variable.
  299.  *                 help - is this a help file?
  300.  *                 page - Is there a page to display?
  301.  *    Returns: none.
  302.  */
  303.  
  304. static void
  305. StartManpage(man_globals, help, page)
  306. ManpageGlobals * man_globals;
  307. Boolean help, page;
  308. {
  309.   Widget dir = man_globals->manpagewidgets.directory;
  310.   Widget manpage = man_globals->manpagewidgets.manpage;
  311.   Widget label = man_globals->label;
  312.   Arg arglist[1];
  313.  
  314. /* 
  315.  * If there is a helpfile then put up both screens if both_show is set.
  316.  */
  317.  
  318.   if (page || help) {
  319.     if (help) 
  320.       strcpy(man_globals->manpage_title, "Xman Help");
  321.  
  322.     if (man_globals->both_shown) {
  323.       XtManageChild(dir);
  324.       man_globals->dir_shown = TRUE;
  325.  
  326.       XtSetArg(arglist[0], XtNpreferredPaneSize, resources.directory_height);
  327.       XtSetValues(dir, arglist, (Cardinal) 1);
  328.  
  329.       XtSetArg(arglist[0], XtNsensitive, FALSE);
  330.       XtSetValues(man_globals->manpage_entry, arglist, ONE);
  331.       XtSetValues(man_globals->dir_entry, arglist, ONE);
  332.  
  333.       XtSetArg(arglist[0], XtNlabel, SHOW_ONE);
  334.       XtSetValues(man_globals->both_screens_entry, arglist, ONE);
  335.       ChangeLabel(label,
  336.           man_globals->section_name[man_globals->current_directory]);
  337.     }
  338.     else {
  339.       ChangeLabel(label,man_globals->manpage_title);
  340.     }
  341.     XtManageChild(manpage);
  342.     man_globals->dir_shown = FALSE;
  343.   }
  344. /*
  345.  * Since There is file to display, put up directory and do not allow change
  346.  * to manpage, show both, or help.
  347.  */
  348.   else {            
  349.     XtManageChild(dir);
  350.     man_globals->dir_shown = TRUE;
  351.     XtSetArg(arglist[0], XtNsensitive, FALSE);
  352.     XtSetValues(man_globals->manpage_entry,        arglist, ONE);
  353.     XtSetValues(man_globals->help_entry,           arglist, ONE);
  354.     XtSetValues(man_globals->both_screens_entry,   arglist, ONE);
  355.     man_globals->both_shown = FALSE;
  356.     ChangeLabel(label,
  357.         man_globals->section_name[man_globals->current_directory]);
  358.   }
  359.  
  360. /*
  361.  * Start 'er up, and change the cursor.
  362.  */
  363.  
  364.   XtRealizeWidget( man_globals->This_Manpage );
  365.   SaveGlobals( man_globals->This_Manpage, man_globals);
  366.   XtMapWidget( man_globals->This_Manpage );
  367.   AddCursor( man_globals->This_Manpage, resources.cursors.manpage);
  368.   XtSetArg(arglist[0], XtNtransientFor, man_globals->This_Manpage);
  369.   XtSetValues(XtParent(man_globals->standby), arglist, (Cardinal)1);
  370.   XtSetValues(XtParent(man_globals->save), arglist, (Cardinal) 1);
  371.   XtRealizeWidget(XtParent(man_globals->standby));
  372.   XtRealizeWidget(XtParent(man_globals->save));
  373.   AddCursor( XtParent(man_globals->standby), resources.cursors.top);
  374.   AddCursor( XtParent(man_globals->save), resources.cursors.top);
  375.  
  376. /*
  377.  * Set up ICCCM delete window.
  378.  */
  379.   XtOverrideTranslations
  380.       (man_globals->This_Manpage, 
  381.        XtParseTranslationTable ("<Message>WM_PROTOCOLS: RemoveThisManpage()"));
  382.   (void) XSetWMProtocols (XtDisplay(man_globals->This_Manpage),
  383.               XtWindow(man_globals->This_Manpage),
  384.               &wm_delete_window, 1);
  385.  
  386. }
  387.  
  388. /*      Function Name: MenuDestroy
  389.  *      Description: free's data associated with menu when it is destroyed.
  390.  *      Arguments: w - menu widget.
  391.  *                 free_me - data to free.
  392.  *                 junk - not used.
  393.  *      Returns: none.
  394.  */
  395.  
  396. /* ARGSUSED */
  397. static void
  398. MenuDestroy(w, free_me, junk)
  399. Widget w;
  400. XtPointer free_me, junk;
  401. {
  402.   XtFree( (char *) free_me);
  403. }
  404.  
  405. /*      Function Name:   CreateOptionMenu
  406.  *      Description: Create the option menu.
  407.  *      Arguments: man_globals - the manual page globals.
  408.  *                 parent - the button that activates the menu.
  409.  *      Returns: none.
  410.  */
  411.  
  412. static void
  413. CreateOptionMenu(man_globals, parent)
  414. ManpageGlobals * man_globals;
  415. Widget parent;
  416. {
  417.   Widget menu, entry;
  418.   int i;
  419.   static char * option_names[] = {    /* Names of the buttons. */
  420.     DIRECTORY,
  421.     MANPAGE,
  422.     HELP,
  423.     SEARCH,
  424.     BOTH_SCREENS, 
  425.     REMOVE_MANPAGE,
  426.     OPEN_MANPAGE,
  427.     SHOW_VERSION,
  428.     QUIT
  429.   };
  430.  
  431.   menu = XtCreatePopupShell(OPTION_MENU, simpleMenuWidgetClass, parent,
  432.                 NULL, (Cardinal) 0);
  433.   man_globals->option_menu = menu;
  434.   
  435.   for (i = 0 ; i < NUM_OPTIONS ; i++) {
  436.     entry = XtCreateManagedWidget(option_names[i], smeBSBObjectClass,
  437.                   menu, NULL, ZERO);
  438.     XtAddCallback(entry, XtNcallback, OptionCallback, (caddr_t) man_globals);
  439.     switch (i) {
  440.     case 0:
  441.     man_globals->dir_entry = entry;
  442.     break;
  443.     case 1:
  444.     man_globals->manpage_entry = entry;
  445.     break;
  446.     case 2:
  447.     man_globals->help_entry = entry;
  448.     break;
  449.     case 3:
  450.     man_globals->search_entry = entry;
  451.     break;
  452.     case 4:
  453.     man_globals->both_screens_entry = entry;
  454.     break;
  455.     case 5:
  456.     man_globals->remove_entry = entry;
  457.     break;
  458.     case 6:
  459.     man_globals->open_entry = entry;
  460.     break;
  461.     case 7:
  462.     man_globals->version_entry = entry;
  463.     break;
  464.     case 8:
  465.     man_globals->quit_entry = entry;
  466.     break;
  467.     default:
  468.     break;
  469.     }
  470.   }
  471. }
  472.  
  473. /*      Function Name: CreateSectionMenu
  474.  *      Description: Create the Section menu.
  475.  *      Arguments: man_globals - the manual page globals.
  476.  *                 parent - the button that activates the menu.
  477.  *      Returns: none.
  478.  */
  479.  
  480. static void
  481. CreateSectionMenu(man_globals, parent)
  482. ManpageGlobals * man_globals;
  483. Widget parent;
  484. {
  485.   Widget menu, entry;
  486.   int i;
  487.   MenuStruct * menu_struct;
  488.   Arg args[1];
  489.   Cardinal num_args;
  490.   char entry_name[BUFSIZ];
  491.  
  492.   menu = XtCreatePopupShell(SECTION_MENU, simpleMenuWidgetClass, parent,
  493.                 NULL, (Cardinal) 0);
  494.  
  495.   for (i = 0 ; i < sections ; i ++) {
  496.     num_args = 0;
  497.     XtSetArg(args[num_args], XtNlabel, manual[i].blabel); num_args++;
  498.     sprintf(entry_name, "section%d", i);
  499.       
  500.     entry = XtCreateManagedWidget(entry_name, smeBSBObjectClass,
  501.                   menu, args, num_args);
  502.     menu_struct = (MenuStruct *) XtMalloc(sizeof(MenuStruct));
  503.     menu_struct->data = (caddr_t) man_globals;
  504.     menu_struct->number = i;
  505.     XtAddCallback(entry, XtNcallback, DirPopupCallback, (caddr_t) menu_struct);
  506.     XtAddCallback(entry, XtNdestroyCallback,MenuDestroy, (caddr_t)menu_struct);
  507.  
  508.   }
  509. }
  510.  
  511. /*    Function Name: CreateList
  512.  *    Description: this function prints a label in the directory list
  513.  *    Arguments: section - the manual section.
  514.  *    Returns: none
  515.  */
  516.  
  517. static char **
  518. CreateList(section)
  519. {
  520.   char ** ret_list, **current;
  521.   int count;
  522.  
  523.   ret_list = (char **) XtMalloc( (manual[section].nentries + 1) * 
  524.                    sizeof (char *));
  525.  
  526.   for (current = ret_list, count = 0 ; count < manual[section].nentries ;
  527.        count++, current++)
  528.     *current = CreateManpageName(manual[section].entries[count], section,
  529.                  manual[section].flags);
  530.  
  531.   *current = NULL;        /* NULL terminate the list. */
  532.   return(ret_list);
  533. }
  534.  
  535. /*    Function Name: MakeDirectoryBox
  536.  *    Description: make a directory box.
  537.  *    Arguments: man_globals - the psuedo global structure for each manpage.
  538.  *                 parent - this guys parent widget.
  539.  *                 dir_disp - the directory display widget.
  540.  *                 section - the section number.
  541.  *    Returns: none.
  542.  */
  543.  
  544. void
  545. MakeDirectoryBox(man_globals,parent,dir_disp,section)
  546. ManpageGlobals *man_globals;
  547. Widget parent, *dir_disp;
  548. int section;
  549. {
  550.   Arg arglist[10];
  551.   Cardinal num_args;
  552.   char * name, label_name[BUFSIZ];
  553.  
  554.   if (*dir_disp != NULL)    /* If we have one, don't make another. */
  555.     return;
  556.  
  557.   name = manual[section].blabel;   /* Set the section name */
  558.   sprintf(label_name,"Directory of: %s",name);
  559.   man_globals->section_name[section] = StrAlloc(label_name);
  560.  
  561.   num_args = 0;
  562.   XtSetArg(arglist[num_args], XtNlist, CreateList(section));
  563.   num_args++;
  564.   XtSetArg(arglist[num_args], XtNfont, resources.fonts.directory);
  565.   num_args++;
  566.   
  567.   *dir_disp = XtCreateWidget(DIRECTORY_NAME, listWidgetClass, parent,
  568.                  arglist, num_args);
  569.   
  570.   XtAddCallback(*dir_disp, XtNcallback,
  571.         DirectoryHandler, (caddr_t) man_globals);
  572. }
  573.  
  574. /*    Function Name: MakeSaveWidgets.
  575.  *    Description: This functions creates two popup widgets, the please 
  576.  *                   standby widget and the would you like to save widget.
  577.  *    Arguments: man_globals - the psuedo globals structure for each man page
  578.  *                 parent - the realized parent for both popups.
  579.  *    Returns: none.
  580.  */
  581.  
  582. void
  583. MakeSaveWidgets(man_globals, parent)
  584. ManpageGlobals *man_globals;
  585. Widget parent;
  586. {
  587.   Widget shell, dialog; /* misc. widgets. */
  588.   Arg warg[1];
  589.   Cardinal n = 0;
  590.  
  591. /* make the please stand by popup widget. */
  592.   if (XtIsRealized(parent)) {
  593.       XtSetArg(warg[0], XtNtransientFor, parent);    n++;
  594.   }
  595.   shell = XtCreatePopupShell( "pleaseStandBy", transientShellWidgetClass,
  596.                   parent, warg, (Cardinal) n);
  597.  
  598.   man_globals->standby = XtCreateManagedWidget("label", labelWidgetClass, 
  599.                            shell, NULL, (Cardinal) 0);
  600.  
  601.   man_globals->save = XtCreatePopupShell("likeToSave",
  602.                      transientShellWidgetClass,
  603.                      parent, warg, n);
  604.  
  605.   dialog = XtCreateManagedWidget("dialog", dialogWidgetClass, 
  606.                  man_globals->save, NULL, (Cardinal) 0);
  607.  
  608.   XawDialogAddButton(dialog, FILE_SAVE, NULL, NULL);
  609.   XawDialogAddButton(dialog, CANCEL_FILE_SAVE, NULL, NULL);
  610.  
  611.   if (XtIsRealized(parent)) {
  612.       XtRealizeWidget(shell);
  613.       AddCursor(shell,resources.cursors.top);
  614.       XtRealizeWidget(man_globals->save);
  615.       AddCursor(man_globals->save, resources.cursors.top);
  616.   }
  617. }
  618.  
  619. /*      Function Name: FormUpWidgets
  620.  *      Description: Sizes widgets to look nice.
  621.  *      Arguments: parent - the common parent of all the widgets.
  622.  *                 full_size - array of widget names that will he full size.
  623.  *                 half_size - array of widget names that will he half size.
  624.  *      Returns: none
  625.  */
  626.  
  627. void
  628. FormUpWidgets(parent, full_size, half_size)
  629. Widget parent;
  630. char ** full_size, ** half_size;
  631. {
  632.   Widget * full_widgets, * half_widgets, *temp, long_widget;
  633.   Dimension longest, length, b_width;
  634.   int interior_dist;
  635.   Arg arglist[2];
  636.     
  637.   full_widgets = ConvertNamesToWidgets(parent, full_size);
  638.   half_widgets = ConvertNamesToWidgets(parent, half_size);
  639.   
  640.   long_widget = NULL;
  641.   longest = 0;
  642.   XtSetArg(arglist[0], XtNwidth, &length);
  643.   XtSetArg(arglist[1], XtNborderWidth, &b_width);
  644.  
  645. /*
  646.  * Find Longest widget.
  647.  */
  648.  
  649.   for ( temp = full_widgets ; *temp != (Widget) NULL ; temp++) {
  650.     XtGetValues(*temp, arglist, (Cardinal) 2);
  651.     length += 2 * b_width;
  652.     if (length > longest) {
  653.       longest = length;
  654.       long_widget = *temp;
  655.     }
  656.   }
  657.  
  658.   if (long_widget == (Widget) NULL) {          /* Make sure we found one. */
  659.     PopupWarning(GetGlobals(parent), 
  660.          "Could not find longest widget, aborting...");
  661.     XtFree((char *)full_widgets);
  662.     XtFree((char *)half_widgets);
  663.     return;
  664.   }
  665.  
  666. /*
  667.  * Set all other full_widgets to this length.
  668.  */
  669.  
  670.   for ( temp = full_widgets ; *temp != (Widget) NULL ; temp++ )
  671.     if ( long_widget != *temp) {
  672.       Dimension width, border_width;
  673.  
  674.       XtSetArg(arglist[0], XtNborderWidth, &border_width);
  675.       XtGetValues(*temp, arglist, (Cardinal) 1);
  676.     
  677.       width = longest - 2 * border_width;
  678.       XtSetArg(arglist[0], XtNwidth, width);
  679.       XtSetValues(*temp, arglist, (Cardinal) 1);
  680.     }
  681.  
  682. /*
  683.  * Set all the half widgets to the right length.
  684.  */
  685.  
  686.   XtSetArg(arglist[0], XtNdefaultDistance, &interior_dist);
  687.   XtGetValues(parent, arglist, (Cardinal) 1);
  688.   
  689.   for ( temp = half_widgets ; *temp != (Widget) NULL ; temp++) {
  690.     Dimension width, border_width;
  691.  
  692.     XtSetArg(arglist[0], XtNborderWidth, &border_width);
  693.     XtGetValues(*temp, arglist, (Cardinal) 1);
  694.     
  695.     width = (int)(longest - interior_dist)/2 - 2 * border_width;
  696.     XtSetArg(arglist[0], XtNwidth, width);
  697.     XtSetValues(*temp, arglist, (Cardinal) 1);
  698.   }
  699.  
  700.   XtFree((char *)full_widgets);
  701.   XtFree((char *)half_widgets);
  702. }
  703.   
  704. /*      Function Name: ConvertNamesToWidgets
  705.  *      Description: Convers a list of names into a list of widgets.
  706.  *      Arguments: parent - the common parent of these widgets.
  707.  *                 names - an array of widget names.
  708.  *      Returns: an array of widget id's.
  709.  */
  710.  
  711. static Widget *
  712. ConvertNamesToWidgets(parent, names)
  713. Widget parent;
  714. char ** names;
  715. {
  716.   char ** temp;
  717.   Widget * ids, * temp_ids;
  718.   int count;
  719.  
  720.   for (count = 0, temp = names; *temp != NULL ; count++, temp++);
  721.  
  722.   ids = (Widget *) XtMalloc( (count + 1) * sizeof(Widget));
  723.  
  724.   
  725.   for ( temp_ids = ids; *names != NULL ; names++, temp_ids++) {
  726.     *temp_ids = XtNameToWidget(parent, *names);
  727.     if (*temp_ids == NULL) {
  728.       char error_buf[BUFSIZ];
  729.     
  730.       sprintf(error_buf, "Could not find widget named '%s'", *names);
  731.       PrintError(error_buf);
  732.       XtFree((char *)ids);
  733.       return(NULL);
  734.     }
  735.   }
  736.   
  737.   *temp_ids = (Widget) NULL;
  738.   return(ids);
  739. }
  740.     
  741.